
const s1 = Symbol('foo');
let json = {
  [s1]: 999,
  s2: function() {},
  s3: undefined,
  s4: '',
  s5: null,
  s6: {
    a: 1,
    b: 2
  }
}
// JSON.stringify的局限性
/**
 * 忽略undefined
 * 忽略function
 * 忽略symbol
 */
// console.log(JSON.stringify(json))

function getType(str) {
  let type = Object.prototype.toString.call(str);
  return type.substr(8, type.length - 9).toLowerCase();
}

function stringify(json) {
  if(typeof json !== 'object' || getType(json) === 'null' || getType(json) === 'undefined') {
    return String(json);
  }
  let isarray = getType(json) === 'array';
  let jsonStr = [];
  for (const key in json) {
    if (Object.hasOwnProperty.call(json, key)) {
      let element = json[key];
      let elType = getType(element);
      // 递归调用
      if(typeof element === 'object') {
        element = stringify(element);
      } else if(['symbol', 'undefined', 'function'].indexOf(elType) !== -1) {
        delete json[key];
        continue;
      } else {
        element = ['string'].indexOf(elType) !== -1 ? `"${element}"` : element;
      }
      jsonStr.push((isarray ? "" : '"' + key + '":') + `${String(element)}`);
    }
  }
  return isarray ? `[${String(jsonStr)}]` : `{${String(jsonStr)}}`;
}

function myJsonStringify(obj) {
  let type = typeof obj;
  if (type !== "object" || type === null) {
      if (/string|undefined|function/.test(type)) {
          obj = '"' + obj + '"';
      }
      return String(obj);
  } else {
      let json = [],
          arr = (obj && obj.constructor === Array);

      for (let k in obj) {
          let v = obj[k];
          let type = typeof v;

          if (/string|undefined|function/.test(type)) {
              v = '"' + v + '"';
          } else if (type === "object") {
              v = myJsonStringify(v);
          }

          json.push((arr ? "" : '"' + k + '":') + String(v));
      }
      return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}")
  }
}

function parse(jsonStr) {
  return new Function(`return ${jsonStr}`)();
}

var ss = stringify({
  a: 1,
  b: 2,
  d: undefined,
  f: null,
  g: [1,2,3,4],
  c: {
    v: 'sss',
    v2: Symbol('foo'),
    v3: function() {console.log(arguments)},
    f: [{
      v1: '333',
      v2: '444'
    }, {
      v1: '00',
      v2: 'ppp'
    }]
  }
});
// console.log(ss);
// console.log(parse(ss).c.f)